本文摘要背景LNMP(Linux + Nginx + MySQL + PHP)是 PHP 开发者最熟悉的环境组合。虽然在服务器上手搓安装也不算难,但换服务器、换系统、或者想快速搭建一套开发环境时,重复操作还是挺烦人的。恰好博客目前跑在 Docker 上(参见《Docker 化部署 Typecho 完整指南》),所以这套 LNMP 也用 Docker Compose 来编排,干净、可复现、随时拆掉重来。环境...

背景
LNMP(Linux + Nginx + MySQL + PHP)是 PHP 开发者最熟悉的环境组合。虽然在服务器上手搓安装也不算难,但换服务器、换系统、或者想快速搭建一套开发环境时,重复操作还是挺烦人的。
恰好博客目前跑在 Docker 上(参见《Docker 化部署 Typecho 完整指南》),所以这套 LNMP 也用 Docker Compose 来编排,干净、可复现、随时拆掉重来。
环境规划
这套方案的目标:在单台服务器上用 Docker Compose 跑起 LNMP,能跑多个 PHP 站点,PHP 和 Nginx 分开容器,方便单独调整。
服务组成
| 服务 | 镜像 | 用途 |
|---|---|---|
nginx | nginx:stable-alpine | Web 服务器 / 反向代理 |
php | php:8.2-fpm-alpine | PHP 解析 |
mysql | mysql:8.0 | 数据库 |
phpmyadmin | phpmyadmin:latest | 数据库管理(可选,开发环境用) |
目录结构
~/lnmp/
├── docker-compose.yml
├── nginx/
│ ├── conf.d/
│ │ └── default.conf
│ └── html/
│ └── index.php
├── php/
│ └── php.ini
└── mysql/
└── data/ # 数据持久化目录部署步骤
第一步:创建目录结构和配置文件
mkdir -p ~/lnmp/{nginx/conf.d,nginx/html,php,mysql/data}
cd ~/lnmp第二步:编写 docker-compose.yml
version: "3.8"
services:
nginx:
image: nginx:stable-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/html:/var/www/html
- ./php:/var/www/php
depends_on:
- php
networks:
- lnmp
php:
image: php:8.2-fpm-alpine
volumes:
- ./nginx/html:/var/www/html
- ./php/php.ini:/usr/local/etc/php/php.ini
expose:
- "9000"
networks:
- lnmp
mysql:
image: mysql:8.0
ports:
- "3306:3306"
volumes:
- ./mysql/data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: <your-mysql-root-password>
MYSQL_DATABASE: app
MYSQL_USER: app_user
MYSQL_PASSWORD: <your-app-user-password>
networks:
- lnmp
phpmyadmin:
image: phpmyadmin:latest
ports:
- "8080:80"
environment:
PMA_HOST: mysql
PMA_PORT: 3306
depends_on:
- mysql
networks:
- lnmp
networks:
lnmp:几个设计要点:
- Nginx 和 PHP 通过容器网络通信,Nginx 通过
php:9000地址转发给 FPM,不暴露 PHP 端口到宿主机 - MySQL 暴露了 3306 端口,方便用 Navicat 等客户端连接;如果不需要外连,去掉
ports字段只保留expose - phpMyAdmin 开在 8080 端口,开发环境方便操作数据库,线上环境建议去掉
- 数据库的 root 密码和应用用户密码放在环境变量里,线上请改用
.env文件
第三步:配置 Nginx
nginx/conf.d/default.conf:
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
include fastcgi_params;
}
}注意 fastcgi_pass 写的是 php:9000——因为 Compose 中服务名叫 php,Docker 内部 DNS 会自动解析。
第四步:PHP 配置
php/php.ini(只列出几个常用参数,其余用默认值):
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
max_execution_time = 300
date.timezone = Asia/Shanghai第五步:启动
docker compose up -d查看启动状态:
docker compose ps预期输出四个服务都是 Up 状态。
第六步:验证
创建一个测试文件 nginx/html/index.php:
<?php
phpinfo();浏览器访问 http://<服务器IP>,应该能看到 PHP 信息页面。往下翻到数据库部分,确认 MySQL 连接正常。
也可以写个简单的连接测试:
<?php
$host = 'mysql';
$user = 'app_user';
$pass = '<your-app-user-password>';
$db = 'app';
try {
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8mb4", $user, $pass);
echo '数据库连接成功';
} catch (PDOException $e) {
echo '连接失败: ' . $e->getMessage();
}用 mysql 这个主机名能连接上,说明 Docker 内部网络通了。
部署多个站点
同一台服务器上想跑多个 PHP 站点,只需在 nginx/conf.d/ 下加新的 .conf 文件:
server {
listen 80;
server_name blog.cndoor.vip;
root /var/www/blog;
index index.php index.html;
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/blog$fastcgi_script_name;
include fastcgi_params;
}
}把站点文件放到对应的根目录(如 nginx/html/blog/),然后 reload Nginx:
docker compose exec nginx nginx -s reload总结
这套 LNMP 方案的优势:
- 环境隔离——每个服务独立容器,互不干扰
- 可复现——一个
docker compose up -d就能在新服务器上拉起整套环境 - 易于扩展——加站点就是加配置文件,不需要动 Nginx 主配置
- 不影响宿主机——不想用了
docker compose down -v即可清理
推荐做法
- 线上环境去掉 phpMyAdmin 容器
- 数据库密码用
.env文件管理,不要硬编码在 docker-compose.yml 里 - PHP 和 Nginx 分开容器是对的——升级 PHP 版本时只需改镜像标签重启一个容器
- MySQL 数据目录
./mysql/data要定期备份
参考
觉得内容不错?我要